/*
 * Copyright 2011 Romain Gilles
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 *
 */
package org.jvdb;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * @author romain.gilles
 */
class SimpleConnectionWrapper extends AbstractConnectionWrapper {

    private final TimerFactory<? extends IPreparedStatementTimer> timerFactory;

    SimpleConnectionWrapper(int connectionId, Connection delegate, TimerFactory<? extends IPreparedStatementTimer> timerFactory) {
        super(delegate, connectionId);
        this.timerFactory = timerFactory;
    }

    //~--------------------------------------------------------------------------------PrepareStatement
    public PreparedStatement prepareStatement(String sql) throws SQLException {
        return newPreparedStatementWrapper(sql, delegate.prepareStatement(sql));
    }

    private PreparedStatementWrapper newPreparedStatementWrapper(String sql, PreparedStatement preparedStatement) {
        return PreparedStatementWrapper.newPreparedStatementWrapper(this, preparedStatement, sql, counter.getAndIncrement(), timerFactory.newTimer(connectionId, counter.getAndIncrement(), sql));
    }

    public PreparedStatement prepareStatement(String sql, int resultSetType,
                                              int resultSetConcurrency) throws SQLException {
        return newPreparedStatementWrapper(sql, delegate.prepareStatement(sql, resultSetType,
                resultSetConcurrency));
    }

    public PreparedStatement prepareStatement(String sql, int resultSetType,
                                              int resultSetConcurrency, int resultSetHoldability)
            throws SQLException {
        return newPreparedStatementWrapper(sql, delegate.prepareStatement(sql, resultSetType,
                resultSetConcurrency, resultSetHoldability));
    }

    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
            throws SQLException {
        return newPreparedStatementWrapper(sql, delegate.prepareStatement(sql, autoGeneratedKeys));
    }

    public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
            throws SQLException {
        return newPreparedStatementWrapper(sql, delegate.prepareStatement(sql, columnIndexes));
    }

    public PreparedStatement prepareStatement(String sql, String[] columnNames)
            throws SQLException {
        return newPreparedStatementWrapper(sql, delegate.prepareStatement(sql, columnNames));
    }

    //~--------------------------------------------------------------------------------CallableStatement
    public CallableStatement prepareCall(String sql) throws SQLException {
        return newCallableStatement(sql, delegate.prepareCall(sql));
    }

    public CallableStatement prepareCall(String sql, int resultSetType,
                                         int resultSetConcurrency, int resultSetHoldability)
            throws SQLException {
        return delegate.prepareCall(sql, resultSetType, resultSetConcurrency,
                resultSetHoldability);
    }

    public CallableStatement prepareCall(String sql, int resultSetType,
                                         int resultSetConcurrency) throws SQLException {
        return newCallableStatement(sql, delegate.prepareCall(sql, resultSetType, resultSetConcurrency));
    }

    private CallableStatementWrapper newCallableStatement(String sql, CallableStatement callableStatement) {
        return CallableStatementWrapper.newCallableStatementWrapper(this, callableStatement, sql, counter.getAndIncrement(), timerFactory.newTimer(connectionId, counter.getAndIncrement(), sql));
    }
}
